package com.aishang.javacv.lab.utils;

import org.bytedeco.ffmpeg.avcodec.AVPacket;
import org.bytedeco.ffmpeg.avformat.AVStream;
import org.bytedeco.javacv.*;
import org.bytedeco.javacv.Frame;

import javax.sound.sampled.*;
import javax.swing.*;
import java.awt.*;
import java.nio.ByteBuffer;
import java.nio.ShortBuffer;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

public class VideoUtils {
    //打开直播
    public static void main (String[] args) {
        //从rtmp服务器拉流 通过nginx的rtmp模块可迅速简单搭建 单纯的rtmp速度也有3s左右的误差 改为通过websocket传输
//        play("rtsp://172.24.254.24:8554/AVfiles/recordVideo.ts");
//        play("rtmp://rtmp01open.ys7.com/openlive/eaf570fc54eb4fac83938859859528d7");
        play("https://flvopen.ys7.com:9188/openlive/eaf570fc54eb4fac83938859859528d7.flv");
//        play("https://hls01open.ys7.com/openlive/eaf570fc54eb4fac83938859859528d7.m3u8");
        //流直播
    }
    public static void play(String filepath) {
        Thread playThread = new Thread(new Runnable() {
            @Override
        public void run() {
            try {
                //开始抓取
                @SuppressWarnings("resource")
                final FFmpegFrameGrabber grabber = new FFmpegFrameGrabber(filepath);
                grabber.start();
                //初始化视图
                CanvasFrame canvas = new CanvasFrame("监控视频",CanvasFrame.getDefaultGamma() / grabber.getGamma());//新建一个窗口
                canvas.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                OpenCVFrameConverter.ToIplImage toIplImage = new OpenCVFrameConverter.ToIplImage();
                //初始化扬声器
//                final AudioFormat audioFormat = new AudioFormat(grabber.getSampleRate(), 16, grabber.getAudioChannels(), true, true);
//                final DataLine.Info info = new DataLine.Info(SourceDataLine.class, audioFormat);
//                final SourceDataLine soundLine = (SourceDataLine) AudioSystem.getLine(info);
//                soundLine.open(audioFormat);
//                soundLine.start();
                //图像转换器 将帧中的image相关信息提取出来
                final Java2DFrameConverter converter = new Java2DFrameConverter();

                ExecutorService executor = Executors.newSingleThreadExecutor();

                while (!Thread.interrupted()) {
                    Frame frame = grabber.grab();
                    if (frame == null) {
                        break;
                    }

                    //帧 为图像帧 或 声音帧
                    if (frame.image != null) {
                        Image image = converter.convert(frame);
                        new Runnable() {
                            @Override
                            public void run() {
                                canvas.showImage(image);
                            }}.run();
                    } else if (frame.samples != null) {
                        final ShortBuffer channelSamplesShortBuffer = (ShortBuffer) frame.samples[0];
                        channelSamplesShortBuffer.rewind();

                        final ByteBuffer outBuffer = ByteBuffer.allocate(channelSamplesShortBuffer.capacity() * 2);

                        for (int i = 0; i < channelSamplesShortBuffer.capacity(); i++) {
                            short val = channelSamplesShortBuffer.get(i);
                            outBuffer.putShort(val);
                        }
                        /*
                         * 写入到扬声器
                         *   并准备下一次读取
                         */
                        try {
                            executor.submit(new Runnable() { public void run() {
//                                soundLine.write(outBuffer.array(), 0, outBuffer.capacity());
                                outBuffer.clear();
                            }}).get();
                        } catch (InterruptedException interruptedException) {
                            Thread.currentThread().interrupt();
                        }
                    }
                }
                executor.shutdownNow();
                executor.awaitTermination(10, TimeUnit.SECONDS);
//                soundLine.stop();
                grabber.stop();
                grabber.release();
            } catch (Exception exception) {
                exception.printStackTrace();
                System.exit(1);
            }
        }});
        playThread.start();

    }

    public void test() throws FFmpegFrameGrabber.Exception {
        FFmpegFrameGrabber grabber = new FFmpegFrameGrabber("rtmp://rtmp01open.ys7.com/openlive/eaf570fc54eb4fac83938859859528d7");
        AVPacket avPacket = grabber.grabPacket();
        AVStream avStream = new AVStream(avPacket);

    }
}
